package com.king.java.tools.ssh.impl;

import com.jcraft.jsch.*;
import com.king.java.tools.ssh.AbstractSSHutils;
import com.king.java.tools.ssh.RemoteInfo;
import com.king.java.tools.ssh.SSHUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述:
 *
 * @author : sujinchen
 * @date : 2020/10/21
 */
public class JschSSHutils extends AbstractSSHutils implements SSHUtils {
    private Logger log = LoggerFactory.getLogger(JschSSHutils.class);

    /**
     * ssh登陆
     *
     * @param remoteInfo 远程主机信息
     * @return
     */
    @Override
    public String ssh(RemoteInfo remoteInfo) {
        JSch jSch = new JSch();
        String key = "";
        Session session = null;
        try {
            //优先使用填入的ssh_key去尝试登陆
            if (Files.exists(Paths.get(remoteInfo.getIdentity()))) {
                jSch.addIdentity(remoteInfo.getIdentity(), remoteInfo.getPassphrase());
            }
            //尝试失败后才使用password登陆
            session = jSch.getSession(remoteInfo.getUser(), remoteInfo.getHost(), remoteInfo.getPort());
            session.setPassword(remoteInfo.getPassword());
            session.setConfig("StrictHostKeyChecking", "no");
            session.connect();
            if (session.isConnected()) {
                key = getKey("Jsch");
            } else {
                key = "failed";
            }
        } catch (JSchException e) {
            e.printStackTrace();
            key = "exception";
        }
        setSSH(key, session);
        return key;
    }

    /**
     * 通过key获取连接并发送指令
     *
     * @param key     连接主机的ID
     * @param command shell指令
     * @return
     */
    @Override
    public List<String> send(String key, String command) {
        List<String> resultLines = new ArrayList<>();
        Session session = (Session) getSSH(key);
        InputStream in = null;
        if (session == null) {
            resultLines.add("session is not exist!");
        } else {
            ChannelExec exec = null;
            try {
                exec = (ChannelExec) session.openChannel("exec");
                exec.setCommand(command);
                exec.setErrStream(System.err);
                exec.connect();
                in = exec.getInputStream();
                boolean connected = exec.isConnected();
                log.info("exec is connected："+connected);
                System.out.println(command);
                if (connected) {
                        bufferRead(resultLines, in);
                }
            } catch (JSchException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (exec != null) {
                    exec.disconnect();

                }
                if (session != null) {
                    session.disconnect();
                    removeSSH(key);
                }
            }
        }
        log.info(command+":"+resultLines);
        return resultLines;
    }


    /**
     * 交互方式执行
     * @param key 连接主机的ID
     * @param in 输入流 System.in
     * @param out 输出流 System.out
     */
        @Override
    public void interaction(String key, InputStream in, OutputStream out) {
        Session ssh = (Session) getSSH(key);
        if (ssh == null) {
            return;
        }
        //获取shell通道
        ChannelShell shell = null;
        try {
            shell = (ChannelShell) ssh.openChannel("shell");
            //获取目标主机输入流，读取执行命令后的结果
            shell.setInputStream(in);
            shell.setPty(true);

            shell.connect();

            //获取目标主机输出流，写入执行命令
            shell.setOutputStream(out);
            InputStream inputStream = shell.getInputStream();
            byte[] tmp=new byte[1024];
            while(true){
                try{Thread.sleep(1000);}catch(Exception ee){}
                while(inputStream.available()>0){
                    int i=inputStream.read(tmp, 0, 1024);
                    if(i<0) {
                        break;
                    }
                    System.out.print(new String(tmp, 0, i));
                }
                if(shell.isClosed()){
                    if(inputStream.available()>0) {
                        continue;
                    }
                    System.out.println("exit-status: "+shell.getExitStatus());
                    break;
                }
            }
            shell.disconnect();
            ssh.disconnect();
        } catch (JSchException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            shell.disconnect();
            ssh.disconnect();
        }

        }

    @Override
    public List<String> sends(String key, String[] commands) {
        return null;
    }


    public static void main(String[] args) {
        SSHUtils utils = new JschSSHutils();
        RemoteInfo remoteInfo = new RemoteInfo();
        remoteInfo.setHost("192.168.102.170");
        remoteInfo.setUser("droid");
        remoteInfo.setPassword("1");
        String ssh = utils.ssh(remoteInfo);
        String command = "screen -r \n\r ps -ef|grep -i screen \n\r screen -S go\n\r cd\n\r cd\n\r source /home/droid/autoTestDir/go.sh \n\r";
//        String command = "screen -r go\n\r ";
//        List<String> pwd = utils.send(ssh, command);
//        System.out.println(command+":\n"+pwd);
        utils.interaction(ssh, System.in, System.out);

    }


}
